import 'index.dart';

class CommonObservable {
  CommonObservable._();

  static final CommonObservable _instance = CommonObservable._();

  factory CommonObservable() => _instance;

  final Map<String, Set<CommonObserver>> _observerList = {};

  ///发布
  void publishChange(String key, [dynamic value]) {
    if (_observerList.isEmpty) {
      Log.log("CommonObservable: empty, return");
      return;
    }
    bool keyContains = _observerList.containsKey(key);
    if (!keyContains) {
      Log.log("CommonObservable: publishChange $key not exist");
      return;
    }
    if (_observerList[key]!.isEmpty) {
      Log.log("CommonObservable: publishChange $key is empty");
      return;
    }
    Log.log("CommonObservable: publishChange $key and size = ${_observerList.length}");
    for (var element in _observerList[key]!) {
      element(key, value);
    }
  }

  ///添加观察者
  void addObserver(String key, CommonObserver observer) {
    bool keyContains = _observerList.containsKey(key);
    bool valueContains = _observerList[key]?.contains(observer) ?? false;
    bool contains = keyContains && valueContains;
    assert(!contains);
    if (contains) {
      Log.log("CommonObservable: addObserver $key and ${observer.runtimeType} exist");
      return;
    }
    Log.log("CommonObservable: addObserver $key");
    if (!keyContains) {
      _observerList[key] = {}..add(observer);
    } else {
      _observerList[key]!.add(observer);
    }
  }

  ///移除观察者,如果[observer]为空，则移除[key]对应的所有观察者
  void removeObserver(String key, CommonObserver observer) {
    bool contains = _observerList[key]?.contains(observer) ?? false;
    if (!contains) {
      Log.log("CommonObservable: removeObserver no observer = $key");
      return;
    }
    Log.log("CommonObservable: removeObserver $key");
    _observerList[key]!.remove(observer);
    if (_observerList[key]!.isEmpty) {
      _observerList.remove(key);
    }
  }

  ///移除key的所有观察者
  void cleanKeyObserver(String key) {
    bool contains = _observerList.containsKey(key);
    if (!contains) {
      Log.log("CommonObservable: cleanKeyObserver no key = $key");
      return;
    }
    _observerList.remove(key);
  }

  ///清空
  void clean() {
    _observerList.clear();
  }

  void debug() {
    _observerList.forEach((key, value) {
      Log.log('$key -- ${value.length}');
    });
  }
}

typedef CommonObserver = void Function(String key, [dynamic value]);
